﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Drawing;
using System.Linq;
using System.Xml;
using System.Net;
using System.Xml.Linq;
using System.Text;
using System.Windows.Forms;

namespace ClientGui
{
    public partial class Form1 : Form
    {
        ListBox lB;
        List<string> currentVisible;
        List<string> WmiCalls;
        Boolean modeD;
        DataSet ds;
        DataSet dt;
        String servicePath;


        public Form1()
        {
            servicePath = "http://localhost:2703/";
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            if (!checkService(servicePath))
            {
                MessageBox.Show("Service is not running");
                this.Close();
            }
            //InitializeData();
            InitializeN();
        }

        private bool checkService(string url)
        {
            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

                using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse())
                {
                    if (rsp.StatusCode == HttpStatusCode.OK)
                    {
                        return true;
                    }
                }
            }
            catch (WebException)
            {
            }

            return false;
        }

        // Se servicePath e' nullo prova a prendere l'xml da filepath
        private DataSet getXml(string servicePath, string filePath = @"C:\Program Files (x86)\WMIService\info.xml")
        {
            DataSet dl = new DataSet();
            try
            {
                if (servicePath == "")
                {
                    dl.ReadXml(filePath);
                }
                else
                {
                    XDocument xml = XDocument.Load(servicePath);
                    File.WriteAllText(filePath, xml.ToString(), Encoding.UTF8);
                    dl.ReadXml(filePath);
                }
            }
            catch (Exception e)
            {
                return null;
            }
            return dl;
        }

        private void cTables_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (modeD)
            {
                if (cTables.SelectedIndex != -1)
                {
                    tableViewer.DataSource = ds.Tables[cTables.SelectedIndex];
                    lTableName.Text = cTables.SelectedItem.ToString();
                    DataColumn[] ddc = new DataColumn[ds.Tables[cTables.SelectedIndex].Columns.Count];
                    ds.Tables[cTables.SelectedIndex].Columns.CopyTo(ddc, 0);
                    contextMenuStrip1.Items.Clear();
                }
            }
            else
            {
                viewTable();
            }
        }

        private void addTables(bool query = false)
        {
            cTables.Items.Clear();
            foreach (DataTable t in ds.Tables)
            {
                if (!query)
                {
                    if (t.Columns.Contains("ID"))
                    {
                        t.Columns.Remove("ID");
                        t.Columns.Remove("MachineName");
                        t.Columns.Remove("InsertDate");
                    }
                }
                cTables.Items.Add(t.ToString());
            }
        }

        #region DataGridVersion

        private void InitializeData()
        {
            modeD = true;
            cTables.Visible = true;
            tableViewer.Visible = true;
            bSave.Visible = true;
            lTableName.Visible = true;
            tQuery.Visible = true;
            bQuery.Visible = true;
            lQuery.Visible = true;
            btDelete.Visible = true;

            ds = new DataSet();
            ds = getXml(servicePath + "/GetAllClasses");
            // ds = getXml("", @"C:\Program Files (x86)\WMIService\cfg.xml");
            addTables();
            cTables.SelectedIndex = 0;

        }

        private void btDelete_Click(object sender, EventArgs e)
        {
            cTables.Items.RemoveAt(cTables.SelectedIndex);
        }

        private void bQuery_Click(object sender, EventArgs e)
        {
            //Devo creare un nuovo dataset senno da errore D>
            DataSet dl = new DataSet();
            string query = tQuery.Text;
            string queryName = "";
            if (!ds.Tables.Contains(query))
            {
                if (ds.Tables[ds.Tables.Count - 1].ToString().Contains("Query"))
                {
                    queryName = "Query" + (Int32.Parse(ds.Tables[ds.Tables.Count - 1].ToString().Replace("Query", "")) + 1).ToString();
                }
                else
                {
                    queryName = "Query1";
                }

                dl = getXml(servicePath + "/GetClassesByQuery?=" + query);
                if (dl != null)
                {
                    dl.Tables[0].TableName = queryName;
                    ds.Merge(dl);
                    addTables(true);
                }
                else
                {
                    MessageBox.Show("Malformed query");
                }

            }
        }

        private void bSave_Click(object sender, EventArgs e)
        {
            saveFile.Filter = "xml|*.xml";
            saveFile.ShowDialog();
            if (saveFile.FileName != "")
            {
                ds.WriteXml(saveFile.FileName);
            }
        }

        private void tableViewer_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                contextMenuStrip1.Show(tableViewer, tableViewer.PointToClient(Cursor.Position));
            }
        }

        #endregion

        #region NormalVersion

        private void InitializeN()
        {
            WmiCalls = new List<string>();
            currentVisible = new List<string>();
            modeD = false;
            cTables.Visible = true;
            ds = new DataSet();
            dt = new DataSet();

            ds = getXml("", @"C:\Program Files (x86)\WMIService\cfg.xml");
            addTablesNormal();
            lB = new ListBox();
            lB.Name = "lB";
            lB.Location = new Point(cTables.Location.X + 20 + cTables.Width, cTables.Location.Y);
            lB.SelectedIndexChanged += new EventHandler(lB_SelectedIndexChanged);
            lB.Width = cTables.Width;
            lB.Height = cTables.Height;
            lB.Visible = false;
            Controls.Add(lB);

        }



        private void viewTable()
        {
            changeVisible("");
            DataTable tl = new DataTable();
            int x = cTables.Width + cTables.Location.X + 50;
            int y = cTables.Location.Y;
            lB.Items.Clear();
            if (cTables.SelectedIndex > -1)
            {
                foreach (DataRow r in ds.Tables[cTables.SelectedIndex + 1].Rows)
                {
                    tl = getXmlQueryN(ds.Tables[cTables.SelectedIndex + 1].ToString(), r["WMI"].ToString());
                    if (tl.Rows.Count > 1)
                    {
                        lB.Visible = true;

                        foreach (DataRow rr in tl.Rows)
                        {

                            lB.Items.Add(rr[r["WMI"].ToString()]);
                        }
                        break;
                    }
                    else
                    {
                        lB.Visible = false;
                        x = cTables.Width + cTables.Location.X + 50;
                        tl = getXmlQueryN(ds.Tables[cTables.SelectedIndex + 1].ToString(), r["WMI"].ToString());
                        if (checkExist(r.Table.ToString() + r["NAME"].ToString() ))
                        {
                            changeVisible(r.Table.ToString() + r["NAME"].ToString() );
                            changeVisible(r.Table.ToString() + r["WMI"].ToString() );

                            currentVisible.Add(r.Table.ToString() + r["NAME"].ToString() );
                            currentVisible.Add(r.Table.ToString() + r["WMI"].ToString() );
                        }
                        else
                        {

                            Label lt = createLabel(r.Table.ToString() + r["NAME"].ToString() , r["NAME"].ToString());
                            lt.Location = new Point(x, y);
                            lt.Width = 100;
                            currentVisible.Add(lt.Name);

                            Label l = createLabel(r.Table.ToString() + r["WMI"].ToString() , tl.Rows[0][r["WMI"].ToString()].ToString());
                            x += lt.Width + 10;
                            l.Location = new Point(x, y);
                            l.Width = 400;
                            currentVisible.Add(l.Name);

                            Controls.Add(l);
                            Controls.Add(lt);
                            y += 30;
                        }




                    }


                }
            }
        }

        private DataTable getXmlQueryN(string tName, string rName)
        {
            DataTable tt = new DataTable();


            if (!dt.Tables.Contains(tName))
            {
                DataSet dl = new DataSet();
                dl = getXml(servicePath + "/GetClassesByQuery?=" + "SELECT * FROM " + tName);
                dl.Tables["Result"].TableName = tName;
                dt.Merge(dl);
                
            }

            tt = dt.Tables[tName];
            return tt;
        }

        private void addTablesNormal()
        {
            int i = 0;
            cTables.Items.Clear();
            foreach (DataTable t in ds.Tables)
            {
                if (t.ToString() != "Conversion")
                {
                    cTables.Items.Add(ds.Tables["Conversion"].Rows[i]["Name"]);
                    WmiCalls.Add(t.ToString());
                    i++;
                }
            }
        }

        private void changeVisible(string lName)
        {


            if (lName != "")
            {
                Controls[lName].Visible = !Controls[lName].Visible;
            }
            else
            {
                foreach (string s in currentVisible)
                {
                    Controls[s].Visible = false;
                }
                currentVisible.Clear();
            }
        }

        protected Label createLabel(string Name, string t)
        {
            Label l = new Label();
            l.Name = Name;
            l.Text = t;
            return l;
        }

        private bool checkExist(string lName)
        {
            try
            {
                Controls[lName].ToString();
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }

        private void lB_SelectedIndexChanged(object sender, EventArgs e)
        {
            changeVisible("");
            int x = lB.Width + lB.Location.X + 50;
            int y = lB.Location.Y;
            DataTable tl = new DataTable();

            if (cTables.SelectedIndex > -1)
            {
                foreach (DataRow r in ds.Tables[cTables.SelectedIndex + 1].Rows)
                {
                    x = lB.Width + lB.Location.X + 50;
                    tl = getXmlQueryN(ds.Tables[cTables.SelectedIndex + 1].ToString(), r["WMI"].ToString());
                    if (checkExist(r.Table.ToString() + r["NAME"].ToString() + lB.SelectedIndex.ToString()))
                    {
                        changeVisible(r.Table.ToString() + r["NAME"].ToString() + lB.SelectedIndex.ToString());
                        changeVisible(r.Table.ToString() + r["WMI"].ToString() + lB.SelectedIndex.ToString());

                        currentVisible.Add(r.Table.ToString() + r["NAME"].ToString() + lB.SelectedIndex.ToString());
                        currentVisible.Add(r.Table.ToString() + r["WMI"].ToString() + lB.SelectedIndex.ToString());
                    }
                    else
                    {

                        Label lt = createLabel(r.Table.ToString() + r["NAME"].ToString() + lB.SelectedIndex.ToString(), r["NAME"].ToString());
                        lt.Location = new Point(x, y);
                        lt.Width = 100;
                        currentVisible.Add(lt.Name);

                        Label l = createLabel(r.Table.ToString() + r["WMI"].ToString() + lB.SelectedIndex.ToString(), tl.Rows[lB.SelectedIndex][r["WMI"].ToString()].ToString());
                        x += lt.Width + 10;
                        l.Location = new Point(x, y);
                        l.Width = 400;
                        currentVisible.Add(l.Name);

                        Controls.Add(l);
                        Controls.Add(lt);
                        y += 30;
                    }

                }
            }

            y = lB.Location.Y;
        }



        #endregion




    }
}
